package org.fast.easy.auth.service.impl;

import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.fast.easy.auth.domain.vo.LoginVo;
import org.fast.easy.auth.service.IAuthStrategy;
import org.fast.easy.auth.service.ISysLoginService;
import org.fast.easy.common.i18n.util.MessageUtils;
import org.fast.easy.common.json.utils.JsonUtils;
import org.fast.easy.core.constant.Constants;
import org.fast.easy.core.constant.GlobalConstants;
import org.fast.easy.core.domain.auth.form.EmailLoginBody;
import org.fast.easy.core.domain.auth.model.LoginUser;
import org.fast.easy.core.enums.LoginType;
import org.fast.easy.core.util.StringUtils;
import org.fast.easy.core.util.ValidatorUtils;
import org.fast.easy.framework.exception.user.CaptchaExpireException;
import org.fast.easy.framework.redis.utils.RedisUtils;
import org.fast.easy.framework.satoken.utils.LoginHelper;
import org.fast.easy.system.client.domain.vo.SysClientVo;
import org.springframework.stereotype.Service;

/**
 * 邮件认证策略
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service("email" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class EmailAuthStrategy extends AbstractAuthStrategy implements IAuthStrategy {

    private final ISysLoginService sysLoginService;
    @Override
    public LoginVo login(String body, SysClientVo client) {
        EmailLoginBody loginBody = JsonUtils.parseObject(body, EmailLoginBody.class);
        ValidatorUtils.validate(loginBody);
        String tenantId = loginBody.getTenantId();
        String email = loginBody.getEmail();
        String emailCode = loginBody.getEmailCode();

        // 通过邮箱查找用户
        LoginUser loginUser = sysLoginService.getLoginUserInfoByEmail(email, tenantId);
        sysLoginService.checkLogin(LoginType.EMAIL, tenantId, loginUser.getUsername(), () -> !validateEmailCode(tenantId, email, emailCode));
        return getUserLoginVo(loginUser, client);
    }

    /**
     * 校验邮箱验证码
     */
    private boolean validateEmailCode(String tenantId, String email, String emailCode) {
        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
        if (StringUtils.isBlank(code)) {
            sysLoginService.recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        return code.equals(emailCode);
    }

}
